//
//  ViewController.m
//  ChatInterface_QQ
//
//  Created by admin on 2019/9/1.
//  Copyright © 2019 猫爷爷的酱醋茶. All rights reserved.
//

#import "ViewController.h"
#import <sys/socket.h>
#import <netinet/in.h>
#import <arpa/inet.h>
#import "Message.h"
#import "MessageFrame.h"
#import "MessageCell.h"

@interface ViewController ()<UITableViewDelegate,UITableViewDataSource,UITextFieldDelegate>

@property(nonatomic,strong)NSMutableArray *messageFrames;
@property (weak, nonatomic) IBOutlet UIView *topView;
@property (weak, nonatomic) IBOutlet UITableView *tableView;
@property (weak, nonatomic) IBOutlet UITextField *textField;
@property (nonatomic,assign)int clientSocket;
@property (nonatomic,copy)NSString *recvMessage;
@property (weak, nonatomic) IBOutlet UISwitch *switchBtn;
- (IBAction)SwitchAct:(id)sender;

@end

@implementation ViewController

//懒加载
- (NSMutableArray *)messageFrames
{
    if (_messageFrames == nil)
    {
        NSString *path = [[NSBundle mainBundle]pathForResource:@"messages.plist" ofType:nil];
        NSArray *arrayDict = [NSArray arrayWithContentsOfFile:path];
        NSMutableArray *arrayM = [NSMutableArray array];
        for (NSDictionary *dict in arrayDict )
        {
            Message *model = [Message messageWithDict:dict];
            
            //获取上一个数据模型
            Message *lastMessage = (Message *)[[arrayM lastObject] message];
            //判断当前模型的“消息发送时间”是否和上一个数据模型的时间一致
            if ([model.time isEqualToString:lastMessage.time])
            {
                model.hideTime = YES;
            }else{
                model.hideTime = NO;
            }
            
            MessageFrame *modelFrame = [[MessageFrame alloc] init];
            modelFrame.message = model;
            
           
            
            [arrayM addObject:modelFrame];
        }
        _messageFrames = arrayM;
    }
    return _messageFrames;
    
}


#pragma mark - UITextFiel的代理方法
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
    if (self.clientSocket == 0)
    {
        [self tipWithMessage:@"请打开网络"];
        return false;
    }
    
    //1.获取用户输入的文本
    NSString *text = textField.text;
    [self sendMessage:text withType:MessageTypeMe];
    
    dispatch_queue_t queue= dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    dispatch_async(queue, ^{
      //线程内
     
      self.recvMessage = [self sendAndRecv:self.textField.text];
      dispatch_async(dispatch_get_main_queue(), ^{
          //回到主线程
          [self sendMessage:self.recvMessage withType:MessageTypeOther];
      });
  });
    
  

    //清空输入框
    textField.text = nil;
    
    
    return YES;
}

//封装一个自动回复的方法
- (void)sendMessage:(NSString *)messageText withType:(MessageType)type
{
    //2.创建一个数据模型和frame模型
    Message *model = [[Message alloc]init];
    //获取当前时间
    NSDate *nowDate = [NSDate date];
    //创建一个日期时间格式化器
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    //设置时间格式
    formatter.dateFormat = @"今天 HH:mm";
    //进行时间格式化
    model.time = [formatter stringFromDate:nowDate];
    model.type = type;
    model.text = messageText;
    
    
    
    //根据当前消息的时间和上一条消息的时间，来设置是否需要隐藏时间label
    MessageFrame *lastModelFrame = [self.messageFrames lastObject];
    
    if ([lastModelFrame.message.time isEqualToString:model.time])
    {
        model.hideTime = YES;
    }
    
    //3.把frame模型加入数组
    MessageFrame *modelFrame = [[MessageFrame alloc]init];
    modelFrame.message = model;
    
    [self.messageFrames addObject:modelFrame];
    
    //4.刷新表格
    [self.tableView reloadData];
    
    //5.把最后一行滚动到最上面
    //把UITableView中的最后一行滚动到最上面
    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:self.messageFrames.count - 1 inSection:0];
    [self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:YES];
    
  
}

#pragma mark - tableView的代理方法
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
    //监听实现收回键盘
    //让当前视图停止编辑
    [self.view endEditing:YES];

}

#pragma mark - tableView的数据源方法

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return self.messageFrames.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    
    //1.获取模型数据
    MessageFrame *modelFrame = self.messageFrames[indexPath.row];
    
    //2.设置单元格
    MessageCell *cell = [MessageCell messgeFrameWithUItableView:tableView];
    
    //3.给单元格设置数据
    cell.messageFrame = modelFrame;
    
    //试着设置输入框的左边视图
//    UIView *leftView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 30, 1)];
//    self.textField.leftView = leftView;
//    self.textField.leftViewMode = UITextFieldViewModeAlways;
    
    //4.返回单元格
    return cell;
    
}

//返回每一行的行高
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    MessageFrame *messageFrame = self.messageFrames[indexPath.row];
    return messageFrame.rowHeight;
}


- (void)viewDidLoad {
    [super viewDidLoad];
    [self.switchBtn setOn:NO];
    
    //隐藏分割线
    self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
    //设置tableView的背景颜色
    self.tableView.backgroundColor = [UIColor colorWithRed:236 / 255.0 green:236 / 255.0 blue:236 / 255.0 alpha:1.0];
    //设置tableView的单元格不允许被选中
    self.tableView.allowsSelection = NO;
    
    
    
    //监听键盘的弹出事件
    //1.创建一个NSNotificationCenter对象
    NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
    
    //2.监听键盘的弹出事件
    [center addObserver:self selector:@selector(keyboardwillChangeFrame:) name:UIKeyboardWillChangeFrameNotification object:nil];
    
    
    
   
}


-(void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];// 1
    [self.textField becomeFirstResponder];// 2
    
}


- (void)keyboardwillChangeFrame:(NSNotification *)noteInfo
{
    /*
     发送事件的对象 (null)
     发送事件的名称 UIKeyboardWillChangeFrameNotification
     事件所包含的信息
     UIKeyboardAnimationCurveUserInfoKey = 7;
     UIKeyboardAnimationDurationUserInfoKey = "0.25";
     UIKeyboardBoundsUserInfoKey = "NSRect: {{0, 0}, {414, 271}}";
     UIKeyboardCenterBeginUserInfoKey = "NSPoint: {207, 871.5}";
     UIKeyboardCenterEndUserInfoKey = "NSPoint: {207, 600.5}";
     UIKeyboardFrameBeginUserInfoKey = "NSRect: {{0, 736}, {414, 271}}";
     UIKeyboardFrameEndUserInfoKey = "NSRect: {{0, 465}, {414, 271}}";
     UIKeyboardIsLocalUserInfoKey = 1;
     
     */
    //    NSLog(@"发送事件的对象%@",noteInfo.object);
    //    NSLog(@"发送事件的名称%@",noteInfo.name);
    //    NSLog(@"事件所包含的信息%@",noteInfo.userInfo);
    
    //获取键盘的Y值
    CGRect recEnd = [noteInfo.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
    CGFloat keyboardY = recEnd.origin.y;
    CGFloat transformValue = keyboardY - self.view.frame.size.height;
    
    [UIView animateWithDuration:0.25 animations:^{
        // 让控制器的View执行一次“平移”
        self.view.transform = CGAffineTransformMakeTranslation(0, transformValue);
        //头部视图保持不变
        self.topView.transform = CGAffineTransformMakeTranslation(0, -transformValue);
        
    }];
    
    
    
    
    //把UITableView中的最后一行滚动到最上面
    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:self.messageFrames.count - 1 inSection:0];
    [self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:YES];
    
}


//----------------- 注意：监听通知一定要在监听通知的对象的dealloc方法中移除监听 防止内存泄漏 ----------------
- (void)dealloc
{
    //移除通知
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

//----------------- 实现网络通信 ----------------

- (BOOL)connectToIP:(NSString *)ip AndPort:(int)port
{
    //1. 创建Socket
    //返回值 如果创建成功返回Socket的描述符，失败-1
    int clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    self.clientSocket = clientSocket;
    
    //2. 连接服务器
    /*
     失败的原因，是12345端口没有被使用。
     连接服务器- 打开Netcat，模拟服务器。
        打开终端>_
            nc -lk 12345
        nc -> Netcat 终端下用于调试和检查网络的工具
     */
    
    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = inet_addr(ip.UTF8String);
    //计算机存储数字的时候，存储的方式不一样，但是网络都是使用大尾顺序，使用htons可以根据计算机转换保证为大尾顺序
    //大尾顺序 - 地址的低位存储值的高位，小尾顺序 - 地址的低位存储值的低位。
    addr.sin_port = htons(port);
    
    int result = connect(clientSocket, (const struct sockaddr *) &addr, sizeof(addr));
    if (result != 0)
    {
        NSLog(@"失败");
        return NO;
    }
    
    return YES;
}

- (NSString *)sendAndRecv:(NSString *)sendMsg
{
    const char *msg = sendMsg.UTF8String;
    ssize_t sendCount = send(self.clientSocket, msg, strlen(msg), 0);
    NSLog(@"发送的字符数 %zd",sendCount);
    
    
    //4. 接收服务器发送的消息
    //返回的是实际的字节个数
    uint8_t buffer[1024];
    ssize_t recvCount = recv(self.clientSocket, buffer, sizeof(buffer), 0);
    NSLog(@"接收的字节数 %zd",recvCount);
    
    //把字节数组转换为字符串
    NSData *data = [NSData dataWithBytes:buffer length:recvCount];
    NSString *recvMessage = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    return recvMessage;
}

//提示弹窗

- (void)tipWithMessage:(NSString *)message
{

      UILabel * tipLabel = [[UILabel alloc] initWithFrame:CGRectMake(UIScreen.mainScreen.bounds.size.width/2 - 60, UIScreen.mainScreen.bounds.size.height/2, 120, 30)];
      // 设置提示内容
      [tipLabel setText:message];
      tipLabel.backgroundColor = [UIColor blackColor];
      tipLabel.layer.cornerRadius = 5;
      tipLabel.layer.masksToBounds = YES;
      tipLabel.textAlignment = NSTextAlignmentCenter;
      tipLabel.textColor = [UIColor whiteColor];
      [self.view addSubview:tipLabel];
      // 设置时间和动画效果
      [UIView animateWithDuration:2.0 animations:^{
      tipLabel.alpha = 0.0;
      } completion:^(BOOL finished) {
      // 动画完毕从父视图移除
      [tipLabel removeFromSuperview];
      }];
    
}

- (IBAction)SwitchAct:(id)sender {
    
    BOOL isButtonOn = [self.switchBtn isOn];
    if (isButtonOn) {

        if ([self connectToIP:@"127.0.0.1" AndPort:12345])
        {
            [self tipWithMessage:@"成功连接"];
        }else{
            [self.switchBtn setOn:NO];
            [self tipWithMessage:@"失去连接"];
        }

    }else {
        close(self.clientSocket);
        [self tipWithMessage:@"断开连接"];
    }
}
@end
